<template>
  <view class="expand-box">
    <view class="title-box">
      <view class="title">
        <slot name="title"></slot>
      </view>
      <view
        class="icon"
        :class="{ right: !expand }"
        @click="handleExpand"
      ></view>
    </view>
    <view
      id="content-box"
      class="content-box"
      :style="{
        marginTop: expand ? 0 + 'px' : -contentHeight + 'px',
      }"
    >
      <slot name="content"></slot>
    </view>
  </view>
</template>
 
<script setup>
import { ref, getCurrentInstance, onMounted, onBeforeUpdate } from 'vue'
 
const expand = ref(true)
const contentHeight = ref()
let query
 
onMounted(() => {
  query = uni
    .createSelectorQuery()
    .in(getCurrentInstance())
    .select('#content-box')
  query
    .boundingClientRect((data) => {
      contentHeight.value = data.height
    })
    .exec()
})
 
onBeforeUpdate(() => {
  query
    .boundingClientRect((data) => {
      contentHeight.value = data.height
    })
    .exec()
})
 
function handleExpand() {
  expand.value = !expand.value
}
</script>
 
<style lang="scss" scoped>
.expand-box {
 /* min-height的值必须有，且需与title-box的height保持一致。*/
 /* 如果不设置min-height，当content-box的margin-top绝对值大于自身height值后，会影响expand-box高度*/
  min-height: 80rpx; 
  overflow: hidden; /* 隐藏上移的内容 */
  margin-bottom: 30rpx;
}
.title-box {
  position: relative;
  z-index: 1;
  height: 80rpx;
  background-color: skyblue;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  .title {
    font-weight: bold;
    font-size: 30rpx;
  }
  .icon {
    width: 40rpx;
    height: 40rpx;
    background-size: cover;
    background-image: url('@/static/bg.png');
    transition: transform 0.8s;
  }
  .right {
    transform: rotate(-90deg);
  }
}
.content-box {
  transition: margin-top 0.8s;
}
</style>